package com.gclife.service.impl;

import com.gclife.domain.AuthUser;
import com.gclife.service.AuthService;
import org.jooq.DSLContext;
import org.jooq.Record4;
import org.jooq.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

import static com.gclife.domain.jooq.Tables.*;

@Service
public class AuthServiceImpl implements AuthService {
    @Autowired
    DSLContext dslContext;

    /**
     * 判断指定用户名是否具有指定资源的访问授权
     *
     * @param username
     * @param resource
     * @return
     */
    public boolean isGranted(String username, String resource) {
        Result<Record4<String, String, String, String>> record4s = dslContext.select(USERS.USERNAME, ROLES.NAME, PERMISSIONS.NAME, RESOURCES.VALUE)
                .from(USERS2ROLES)
                .join(USERS).on(USERS.UID.eq(USERS2ROLES.UID))
                .join(ROLES).on(ROLES.ROLE_ID.eq(USERS2ROLES.ROLE_ID))
                .join(PERMISSIONS2ROLES).on(PERMISSIONS2ROLES.ROLE_ID.eq(ROLES.ROLE_ID))
                .join(PERMISSIONS).on(PERMISSIONS.PERMISSION_ID.eq(PERMISSIONS2ROLES.PERMISSION_ID))
                .join(RESOURCES2PERMISSIONS).on(RESOURCES2PERMISSIONS.PERMISSION_ID.eq(PERMISSIONS.PERMISSION_ID))
                .join(RESOURCES).on(RESOURCES.RESOURCE_ID.eq(RESOURCES2PERMISSIONS.RESOURCE_ID))
                .where(USERS.USERNAME.eq(username).and(RESOURCES.VALUE.eq(resource)))
                .fetch();
        return (record4s.size() > 0);
    }

    /**
     * 根据用户名，fetch 该用户所有授权的资源（包括roles和permissions）
     *
     * @param username
     * @return
     */
    public AuthUser fetchGrantedResourcesByUsername(String username) {
        Result<Record4<String, String, String, String>> record4s = dslContext.select(USERS.USERNAME, ROLES.NAME, PERMISSIONS.NAME, RESOURCES.VALUE)
                .from(USERS2ROLES)
                .join(USERS).on(USERS.UID.eq(USERS2ROLES.UID))
                .join(ROLES).on(ROLES.ROLE_ID.eq(USERS2ROLES.ROLE_ID))
                .join(PERMISSIONS2ROLES).on(PERMISSIONS2ROLES.ROLE_ID.eq(ROLES.ROLE_ID))
                .join(PERMISSIONS).on(PERMISSIONS.PERMISSION_ID.eq(PERMISSIONS2ROLES.PERMISSION_ID))
                .join(RESOURCES2PERMISSIONS).on(RESOURCES2PERMISSIONS.PERMISSION_ID.eq(PERMISSIONS.PERMISSION_ID))
                .join(RESOURCES).on(RESOURCES.RESOURCE_ID.eq(RESOURCES2PERMISSIONS.RESOURCE_ID))
                .where(USERS.USERNAME.eq(username))
                .fetch();

        List<String> roles = new ArrayList<>();
        List<String> permissions = new ArrayList<>();
        List<String> resources = new ArrayList<>();
        for (Record4<String, String, String, String> record4 : record4s) {
            if (!roles.contains(record4.get(ROLES.NAME))) roles.add(record4.get(ROLES.NAME));
            if (!permissions.contains(record4.get(PERMISSIONS.NAME))) permissions.add(record4.get(PERMISSIONS.NAME));
            if (!resources.contains(record4.get(RESOURCES.VALUE))) resources.add(record4.get(RESOURCES.VALUE));
        }

        return new AuthUser(username, null, roles, permissions, resources);
    }
}
